#ifndef LOG_HPP
#define LOG_HPP

#include <cstdio>
#include <cstdarg>

#include <boost/format.hpp>

namespace kieper {
    /**
     * Utility functions for logging.
     */
    namespace log {
#ifdef DEBUG
        static const bool debugEnabled = true;
#else
        static const bool debugEnabled = false;
#endif
        enum LogLevel {
            LEVEL_TRACE = 0,
            LEVEL_DEBUG = 1,
            LEVEL_INFO = 2,
            LEVEL_WARN = 3,
            LEVEL_ERROR = 4,
            LEVEL_FATAL = 5
        };

        static const char* LEVEL_NAMES[] = {
            "TRACE",
            "DEBUG", 
            "INFO",
            "WARN",
            "ERROR",
            "FATAL"
        };
__extension__
#define LOG_TRACE(format, ...)  log::logInternal(log::LEVEL_TRACE, format, __FILE__, __LINE__, __VA_ARGS__)

__extension__
#define LOG_DEBUG(format, ...) log::logInternal(log::LEVEL_DEBUG, format, __FILE__, __LINE__, __VA_ARGS__)

#define LOG_INFO(format, ...) \
    log::logInternal(log::LEVEL_INFO, format, __FILE__, __LINE__, __VA_ARGS__)

        inline void logInternal(LogLevel level, const char* format,
            const char* file, unsigned int line, ...) {
            if (debugEnabled) {
                va_list ap;
                va_start(ap, line);
                fprintf(stderr, "%s %s:%u ", LEVEL_NAMES[level], file, line);
                vfprintf(stderr, format, ap);
                fprintf(stderr, "\n");
                va_end(ap);
            }
        }

        /**
         * Checks if debug flag is enabled.
         * @return true if debug flag is enabled, false otherwise
         */
        inline bool isDebugEnabled() {
            return debugEnabled;
        }
    }
}

#endif
